// 引入登录、退出登录、获取用户信息的接口函数
import {login, logout, getInfo} from '@/api/user'
// 获取token、设置token、删除token的函数
import {getToken, setToken, removeToken} from '@/utils/auth'
// 路由模块当中重置路由的方法
import {resetRouter, allAsyncRouter, anyRouter, constantRoutes } from '@/router'
import router from '@/router'

// 箭头函数
const getDefaultState = () => {
    return {
        // 获取token
        token: getToken(),
        // 存储用户名
        name: '',
        // 存储用户头像
        avatar: '',
        // 存储菜单权限标记 , 服务器返回的
        routes:[],
        // 角色   服务器返回的
        roles:[],
        // 按钮权限标志   服务器返回的
        button:[],
        // 对比之后【项目中已有的异步路由，与服务器返回的标记信息进行对比，最终需要展示的路由】
        resultAsyncRoutes:[],
        // 用户最终需要展示的路由
        resultAllRoutes:[]
    }
}

const state = getDefaultState()

const mutations = {
    // 重置token
    RESET_STATE: (state) => {
        Object.assign(state, getDefaultState())
    },
    // 存储token
    SET_TOKEN: (state, token) => {
        state.token = token
    },
    // 存储用户信息
    SET_USERINFO: (state, userInfo) => {
        // 用户名
        state.name = userInfo.name
        // 用户头像
        state.avatar = userInfo.avatar
        // 菜单权限标志
        state.routes = userInfo.routes
        // 角色
        state.roles = userInfo.roles
        // 按钮权限标志
        state.button = userInfo.button
    },
    // 最终计算出来的异步路由
    SET_RESULTASYNCROUTES:(state,asyncResult) =>{
        // vuex保存当前用户的异步路由，注意：一个用户需要展示完整的路由：常量路由、异步路由、任意路由
        state.resultAsyncRoutes = asyncResult
        // 计算出当前用户需要展示的所有路由
        state.resultAllRoutes = constantRoutes.concat(state.resultAsyncRoutes,anyRouter)
        // 给路由器添加新的路由
        router.addRoutes(state.resultAllRoutes)
    }
}

// 定义一个函数，两个数组进行对比，对比出当前用户到底显示哪些异步路由
const computedAsyncRoutes = (allAsyncRouter,routes) => {
    // console.log(allAsyncRouter,111)
    // console.log(routes,222)
    // 过滤出当前用户【超级管理员|普通员工】需要展示的异步路由
    return allAsyncRouter.filter(item => {
        // console.log(item)       // item就是每一个异步路由
        // 数组当中没有这个元素返回-1，如果有，返回的一定不是-1
        if (routes.indexOf(item.name) != -1) {
            // 递归,还有2级、3级、4级。。。路由
            if (item.children&&item.children.length) {
                item.children = computedAsyncRoutes(item.children,routes)
            }
            return true
        }
    })
}

const actions = {
    // 登录业务
    async login({commit}, userInfo) {
        // 解构出用户名和密码
        const {username, password} = userInfo
        let result = await login({username: username.trim(), password: password})
        // console.log(result)
        if (result.code==20000){
            // vuex存储token
            commit('SET_TOKEN', result.data.token)
            // 持久化存储
            setToken(result.data.token)
            return 'OK'
        } else {
            return Promise.reject(new Error('登录失败'))
        }
    },

    // 获取用户信息
    getInfo({commit, state}) {
        return new Promise((resolve, reject) => {
            getInfo(state.token).then(response => {
                // 获取用户信息：返回数据包含：用户名name、用户头像avatar、routes【返回的标志：不同的用户应该展示哪些菜单的标记】、
                //      roles(用户角色的信息)、button【按钮的信息：按钮权限用的标记】
                const {data} = response
                // console.log(data)
                // vuex储存用户的全部信息
                commit('SET_USERINFO',data)

                commit('SET_RESULTASYNCROUTES',computedAsyncRoutes(allAsyncRouter,data.routes))
                if (!data) {
                    return reject('验证失败，请重新登录.')
                }

                resolve(data)
            }).catch(error => {
                reject(error)
            })
        })
    },

    // user logout
    logout({commit, state}) {
        return new Promise((resolve, reject) => {
            logout(state.token).then(() => {
                removeToken() // must remove  token  first
                resetRouter()
                commit('RESET_STATE')
                resolve()
            }).catch(error => {
                reject(error)
            })
        })
    },

    // remove token
    resetToken({commit}) {
        return new Promise(resolve => {
            removeToken() // must remove  token  first
            commit('RESET_STATE')
            resolve()
        })
    }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}

